//
// Created by QU on 24-6-19.
//
#include <iostream>
#include <functional>
#include <utility>
#include <memory>
#include <vector>
#include <map>
#include <set>
#include <new>
#include <thread>
#include <algorithm>
#include <array>
#include <string>
#include <deque>
#include <format>

using std::cout, std::cin, std::endl;

// c++11 noexcept         老写法是throw(), c++17弃用, c++20移除
// noexcept 分为说明符(类似于函数后的override), 和运算符(类似于sizeof)
void f1() noexcept        // 说明符
{ }

void f2() noexcept(true)       // 说明符
{ }

void f3() noexcept(false)       // 说明符
{ }

void f4() noexcept(noexcept(f1))    // noexcept 跟随 f1函数相同
{ }

int main(int argc, char const *argv[]) {
    std::cout << std::boolalpha;

    auto p = f1;
    // c++17后, noexcept异常说明作为类型的一部分.
    // 但是不是函数重载的一部分, 重载仅仅和参数列表有关系.

    std::cout << "f1 noexcept "  << noexcept(f1()) << std::endl;
    std::cout << "f2 noexcept "  << noexcept(f2()) << std::endl;
    std::cout << "f3 noexcept "  << noexcept(f3()) << std::endl;
    std::cout << "f4 noexcept "  << noexcept(f4()) << std::endl;

    // noexcept是不求值表达式, 就像sizeof一样. 在编译器确定的, 里面填任何东西都不会执行.
    // https://zh.cppreference.com/w/cpp/language/expressions#.E6.BD.9C.E5.9C.A8.E6.B1.82.E5.80.BC.E8.A1.A8.E8.BE.BE.E5.BC.8F
    size_t size =  sizeof(std::cout << 666);        // 你会发现666没有打印
    std::cout << "before size: " << size << std::endl;
    noexcept(size++);                               // size没有变化
    std::cout << "after size: " << size << std::endl;


    return 0;
}